﻿using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Songhay.Tests
{
    using Songhay.Extensions;
    using Songhay.Models;
    using Songhay.Net;
    using Songhay.Xml;

    /// <summary>
    /// Summary description for OpmlTest
    /// </summary>
    [TestClass]
    public class OpmlTest
    {
        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize]
        public void InitializeTest()
        {
            #region remove previous test results:

            var directory = Directory.GetParent(TestContext.TestDir);

            directory.GetFiles()
                .OrderByDescending(f => f.LastAccessTime).Skip(1)
                .ForEachInEnumerable(f => f.Delete());

            directory.GetDirectories()
                .OrderByDescending(d => d.LastAccessTime).Skip(1)
                .ForEachInEnumerable(d => d.Delete(true));

            #endregion
        }

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        [TestMethod]
        [Description("Should filter Category")]
        public void ShouldFilterCategory()
        {
            var path = ConfigurationManager.AppSettings.Get("TESTPROJECTFOLDER") + @"Models\OpmlFromInfoPath.xml";
            var xd = XDocument.Load(path);
            var data = OpmlUtility.GetDocument(xd.Root, OpmlUtility.rx);

            Assert.IsTrue(data.OpmlBody.Outlines.Length == 4);

            data.OpmlBody.Outlines = data.OpmlBody.Outlines
                .Where(o => o.Category != "private").ToArray();

            Assert.IsTrue(data.OpmlBody.Outlines.Length == 3);
        }

        [TestMethod]
        [Description("Should load categories and resources.")]
        public void ShouldLoadCategoriesAndResources()
        {
            var path = ConfigurationManager.AppSettings.Get("TESTPROJECTFOLDER") + @"Models\OpmlTest.xml";
            var xd = XDocument.Load(path);
            var data = OpmlUtility.GetDocument(xd.Root, OpmlUtility.rx);

            //XPATH: ./outline[not(@url)]
            var categories = data.OpmlBody.Outlines
                .Where(outline => outline.Url == null);

            categories.ForEachInEnumerable(category =>
                TestContext.WriteLine("Category: " + category.Text));

            //XPATH./outline[@type="link"]
            var resources = categories.First().Outlines
                .Where(outline => outline.OutlineType == "link");

            resources.ForEachInEnumerable(resource =>
                TestContext.WriteLine("Resource: " + resource.Text));
        }

        [TestMethod]
        [Description("Should load document.")]
        public void ShouldLoadDocument()
        {
            var path = ConfigurationManager.AppSettings.Get("TESTPROJECTFOLDER") + @"Models\OpmlFromInfoPath.xml";
            var xd = XDocument.Load(path);
            var data = OpmlUtility.GetDocument(xd.Root, OpmlUtility.rx);

            var expected = "Development Server";
            var actual = data.OpmlHead.Title;
            Assert.AreEqual(expected, actual);

            expected = "LINQ to Entities Paging";
            actual = data.OpmlBody.Outlines
                .Where(o => o.Text == "Samples")
                .First().Outlines.First().Text;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        [Description("Should load remote document.")]
        public void ShouldLoadRemoteDocument()
        {
            OpmlDocument doc = null;

            HttpVerbAsyncUtility.GetOpmlDocument(
                new Uri("http://songhaysystem.com/xml/kinte_links.xml", UriKind.Absolute),
                new Action<OpmlDocument>((opml) => { doc = opml; })
            );

            Thread.Sleep(2000);

            Assert.IsNotNull(doc, "The expected OPML document is not here.");

        }

        [TestMethod]
        public void ShouldWriteDateModified()
        {
            var path = ConfigurationManager.AppSettings.Get("TESTPROJECTFOLDER") + @"Models\OpmlTest.xml";
            var xd = XDocument.Load(path);
            var data = OpmlUtility.GetDocument(xd.Root, OpmlUtility.rx);
            DateTime? date = DateTime.Now;
            data.OpmlHead.DateModified = date;
            XmlUtility.Write(data, path);

            xd = XDocument.Load(path);
            data = OpmlUtility.GetDocument(xd.Root, OpmlUtility.rx);
            var actualDate = data.OpmlHead.DateModified;
            Assert.AreEqual(date.Value.Day, actualDate.Value.Day);
            Assert.AreEqual(date.Value.Hour, actualDate.Value.Hour);
            Assert.AreEqual(date.Value.Minute, actualDate.Value.Minute);
        }
    }
}
